﻿using Microsoft.AspNetCore.Mvc;
using Minio;
using Minio.DataModel.Args;
using Minio.DataModel.Result;
using Newtonsoft.Json;

namespace B.S.BaseData.Write.Api.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FileUploadController : ControllerBase
    {
        private readonly IMinioClient minioClient;
        private string bucketName = "one";

        public FileUploadController()
        {
            minioClient = new MinioClient()
                .WithEndpoint("10.223.8.7:9000")
                .WithCredentials("admin", "admin123")
                .WithSSL(false)
                .Build();
        }

        /// <summary>
        /// 列出所有桶
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> ListBuckets()
        {
            ListAllMyBucketsResult buckets = await minioClient.ListBucketsAsync().ConfigureAwait(false);
            return Ok(buckets);
        }

        /// <summary>
        /// 上传单个文件
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> UploadFile(IFormFile file)
        {
            //检查桶是否存在
            BucketExistsArgs? beArgs = new BucketExistsArgs()
                .WithBucket(bucketName);

            bool fount = await minioClient.BucketExistsAsync(beArgs);

            if (!fount)
            {
                //MakeBucketArgs 是用于配置穿件存储桶操作的参数对象
                MakeBucketArgs? mbArgs = new MakeBucketArgs().WithBucket(bucketName);
                await minioClient.MakeBucketAsync(mbArgs).ConfigureAwait(false);
            }

            //获取文件名
            string? objectName = file.FileName;

            //使用流数据上传文件
            //注意：MINIO API 要求 Content-Type 和 ObjectSize参数
            PutObjectArgs? putArgs = new PutObjectArgs()
                .WithBucket(bucketName)
                .WithObject(objectName)
                .WithStreamData(file.OpenReadStream())
                .WithContentType(file.ContentType)
                .WithObjectSize(file.Length);
            await minioClient.PutObjectAsync(putArgs).ConfigureAwait(false);

            //在服务器端生成一个预签名
            //客户端可以使用该URL来直接下载MinIO存储中的特定对象
            //并将其作为JSON格式的响应数据返回给客户端
            PresignedGetObjectArgs getArgs = new PresignedGetObjectArgs()
                .WithBucket(bucketName)
                .WithObject(objectName)
                .WithExpiry(7200);
            string? url = await minioClient.PresignedGetObjectAsync(getArgs).ConfigureAwait(false);
            return Ok(JsonConvert.SerializeObject(url));
        }
    }
}
